// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <turbo/utility/status.h>
#include <cantor/proto/parser/ast.pb.h>
#include  <cantor/common/log.h>
#include <cantor/resolved/pass_context.h>
#include <cantor/resolved/resolved_path.h>

namespace cantor::resolved {

    class ResolvedContext {
    public:
        ResolvedContext() = default;
        ~ResolvedContext() = default;

        template<typename... Args>
        void log_debug(cantor::common::LogLocation &&loc, Args &&... args) {
            logger.log_debug(loc, cantor::pb::PHASE_RESOLVE, std::forward<Args>(args)...);
        }

        template<typename... Args>
        void log_warn(cantor::common::LogLocation &&loc, Args &&... args) {
            logger.log_warn(loc, cantor::pb::PHASE_RESOLVE, std::forward<Args>(args)...);
        }

        template<typename... Args>
        void log_error(cantor::common::LogLocation &&loc, Args &&... args) {
            logger.log_error(loc, cantor::pb::PHASE_RESOLVE, std::forward<Args>(args)...);
        }

        void set_stmt(const cantor::pb::ast::Statement &st) {
            stmt = st;
            origin_stmt = &st;
        }

        void appy_pass(const std::string &pass) {
            passes.push_back(pass);
        }

        void push_path(cantor::pb::resolved::ResolvedNodeTag tag, google::protobuf::Message *msg) {
            path.push_back(tag, msg);
        }

        void push_path(cantor::pb::resolved::ResolvedNodeTag tag, int index, google::protobuf::Message *msg) {
            path.push_back(tag, index, msg);
        }

        void pop_path() {
            path.pop_back();
        }

    public:
        std::vector<std::string> passes;
        cantor::pb::ast::Statement stmt;
        const cantor::pb::ast::Statement *origin_stmt{nullptr};
        cantor::common::IRLogger logger;
        std::unique_ptr<PassContext> pass_context{nullptr};
        ResolvedPath path;
    };
} // namespace cantor::resolved
